home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
3D Images
/
3D Images.iso
/
programs
/
amiga
/
mpegutils
/
tools
/
src
/
cyuv2ppm.c
next >
Wrap
C/C++ Source or Header
|
1995-01-12
|
7KB
|
251 lines
/*************************************************************
Copyright (C) 1990, 1991, 1993 Andy C. Hung, all rights reserved.
PUBLIC DOMAIN LICENSE: Stanford University Portable Video Research
Group. If you use this software, you agree to the following: This
program package is purely experimental, and is licensed "as is".
Permission is granted to use, modify, and distribute this program
without charge for any purpose, provided this license/ disclaimer
notice appears in the copies. No warranty or maintenance is given,
either expressed or implied. In no event shall the author(s) be
liable to you or a third party for any special, incidental,
consequential, or other damages, arising out of the use or inability
to use the program for any purpose (or the loss of data), even if we
have been advised of such possibilities. Any public reference or
advertisement of this source code should refer to it as the Portable
Video Research Group (PVRG) code, and not by any author(s) (or
Stanford University) name.
*************************************************************/
/*
************************************************************
cyuv2ppm.c
This program converts component YUV files with a sampling ratio of
4:1:1 (the same pattern as MPEG 4:2:0; the files read from .Y .U .V by
default) into a single raw ppm file.
The ppm description and files are part of Jef Poskanzer's PBMPLUS
library. This is just a short-cut program to do a simple RGB
conversion.
-----
Modifications by Son H. Le on 01-Sep-93
o replaced all exit(-1) with exit(0)
o added exit(0) after convertYUV2RGB()
o added #include <stdlib.h> and <string.h>
o added prototype convertYUV2RGB()
************************************************************
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define PPM_MAGIC1 'P'
#define PPM_MAGIC2 '3'
#define RPPM_MAGIC2 '6'
#define FIXNUM 16
#define FIX(a,b) ((int)((a)*(1<<(b))))
#define UNFIX(a,b) ((a+(1<<(b-1)))>>(b))
/* Approximate 255 by 256 */
#define ICCIRUV(x) (((x)<<8)/224)
#define ICCIRY(x) ((((x)-16)<<8)/219)
#define CLIP(t) (((t)>255)?255:(((t)<0)?0:(t)))
#define GETR(y,u,v) UNFIX((FIX(1.0,FIXNUM)*(y)+\
FIX(1.402,FIXNUM)*(v)),FIXNUM)
#define GETG(y,u,v) UNFIX((FIX(1.0,FIXNUM)*(y)+\
FIX(-0.34414,FIXNUM)*(u)+\
FIX(-0.71414,FIXNUM)*(v)),FIXNUM)
#define GETB(y,u,v) UNFIX((FIX(1.0,FIXNUM)*(y)+\
FIX(1.772,FIXNUM)*(u)),FIXNUM)
char *suffix[3] = {".Y",".U",".V"};
void convertYUV2RGB(int cols,int rows,FILE *iny,FILE *inu,FILE *inv,
FILE *out,int CCIR601);
void
convertYUV2RGB(cols, rows, iny, inu, inv, out, CCIR601)
int cols,rows;
FILE *iny,*inu,*inv,*out;
int CCIR601;
{
int i,j;
int y1,y2,y3,y4,u1,v1;
int temp;
unsigned char *temprgb1, *temprgb2, *tempy1, *tempy2, *tempu, *tempv;
unsigned char *rgb1p, *rgb2p, *y1p, *y2p, *up, *vp;
fprintf(out,"%c%c\n%d %d\n%d\n",PPM_MAGIC1,RPPM_MAGIC2,cols,rows,255);
printf("input size: %dx%d\t output size: %dx%d\n",
cols,rows,cols,rows);
temprgb1 = (unsigned char *) calloc(cols*3,sizeof(char));
temprgb2 = (unsigned char *) calloc(cols*3,sizeof(char));
tempy1 = (unsigned char *) calloc(cols,sizeof(char));
tempy2 = (unsigned char *) calloc(cols,sizeof(char));
tempu = (unsigned char *) calloc(cols>>1,sizeof(char));
tempv = (unsigned char *) calloc(cols>>1,sizeof(char));
if ((rows&1)||(cols&1))
{
printf("rows and columns must be multiple of 2\n");
exit(0);
}
for(i=0;i<(rows>>1);i++)
{
fread(tempy1,1,cols*sizeof(char),iny);
fread(tempy2,1,cols*sizeof(char),iny);
fread(tempu,1,(cols>>1)*sizeof(char),inu);
fread(tempv,1,(cols>>1)*sizeof(char),inv);
rgb1p = temprgb1;
rgb2p = temprgb2;
y1p = tempy1;
y2p = tempy2;
up = tempu;
vp = tempv;
for(j=0;j<(cols>>1);j++)
{ /* We use pel replication for interpolation */
y1 = *(y1p++);
y2 = *(y1p++);
y3 = *(y2p++);
y4 = *(y2p++);
u1 = *(up++);
v1 = *(vp++);
u1 -=128;
v1 -=128;
if (CCIR601)
{
y1 = ICCIRY(y1);
y2 = ICCIRY(y2);
y3 = ICCIRY(y3);
y4 = ICCIRY(y4);
u1 = ICCIRUV(u1);
v1 = ICCIRUV(v1);
}
temp=GETR(y1,u1,v1);
*(rgb1p++) = CLIP(temp);
temp=GETG(y1,u1,v1);
*(rgb1p++) = CLIP(temp);
temp=GETB(y1,u1,v1);
*(rgb1p++) = CLIP(temp);
temp=GETR(y2,u1,v1);
*(rgb1p++) = CLIP(temp);
temp=GETG(y2,u1,v1);
*(rgb1p++) = CLIP(temp);
temp=GETB(y2,u1,v1);
*(rgb1p++) = CLIP(temp);
temp=GETR(y3,u1,v1);
*(rgb2p++) = CLIP(temp);
temp=GETG(y3,u1,v1);
*(rgb2p++) = CLIP(temp);
temp=GETB(y3,u1,v1);
*(rgb2p++) = CLIP(temp);
temp=GETR(y4,u1,v1);
*(rgb2p++) = CLIP(temp);
temp=GETG(y4,u1,v1);
*(rgb2p++) = CLIP(temp);
temp=GETB(y4,u1,v1);
*(rgb2p++) = CLIP(temp);
}
fwrite(temprgb1,1,cols*3*sizeof(char),out);
fwrite(temprgb2,1,cols*3*sizeof(char),out);
}
}
int
main(argc, argv)
int argc;
char **argv;
{
int i;
int CCIR601=0;
int width=352,height=240;
int suffixcount=0;
char *infile,*outfile;
char infiley[256];
char infileu[256];
char infilev[256];
FILE *out,*iny,*inu,*inv;
if (argc<3)
{
printf("cyuv2ppm infile outfile [-iw width] [-ih height] [-z suffix]* [-CCIR601]\n");
printf("\n");
printf("width = 352 by default, width of component input file\n");
printf("height = 240 by default, width of component input file\n");
printf("infile is the input yuv file; default infile.Y infile.U infile.V.\n");
printf("outfile is the output ppm file.\n");
printf("-z specifies alternate suffixes:\n");
printf(" e.g. cyuv2ppm inp out.ppm -z .y -z .cb -z .cr\n");
printf(" will input in.y, in.cb, in.cr, respectively\n");
printf("-CCIR601 specifies CCIR601 yuv space (default JFIF).\n");
exit(0);
}
for(i=3;i<argc;i++)
{
if (!strcmp(argv[i],"-z"))
{
if (suffixcount==3)
{
printf("too many suffixes\n");
exit(0);
}
suffix[suffixcount++] = argv[++i];
}
else if (!strcmp(argv[i],"-iw"))
width = atoi(argv[++i]);
else if (!strcmp(argv[i],"-ih"))
height = atoi(argv[++i]);
else if (!strcmp(argv[i],"-CCIR601"))
CCIR601=1;
else
{
printf("unknown option: %s\n",argv[i]);
exit(0);
}
}
infile = argv[1];
outfile = argv[2];
sprintf(infiley,"%s%s",infile,suffix[0]);
sprintf(infileu,"%s%s",infile,suffix[1]);
sprintf(infilev,"%s%s",infile,suffix[2]);
if (!(out=fopen(outfile,"w")))
{
printf("cannot open file: %s\n",outfile);
exit(0);
}
if (!(iny=fopen(infiley,"r")))
{
printf("cannot open file: %s\n",infiley);
exit(0);
}
if (!(inu=fopen(infileu,"r")))
{
printf("cannot open file: %s\n",infileu);
exit(0);
}
if (!(inv=fopen(infilev,"r")))
{
printf("cannot open file: %s\n",infilev);
exit(0);
}
convertYUV2RGB(width,height,iny,inu,inv,out,CCIR601);
exit(0);
}